﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RzCorportativo.DataAccess;

namespace RzCorportativo.Lib
{
    public class Agenda
    {
        public Agenda()
        {
            this.DataConsulta = DateTime.MinValue;
        }

        public int AgendaId { get; set; }
        public int MedicoId { get; set; }
        public int PacienteId { get; set; }
        public short EspecialidadeId { get; set; }
        public DateTime DataConsulta { get; set; }
        private bool avaliadoChanged;
        private bool avaliado;
        public bool Avaliado { get { return this.avaliado; } set { this.avaliado = value; this.avaliadoChanged = true; } }
        private bool aprovadoChanged;
        private bool aprovado;
        public bool Aprovado { get { return this.aprovado; } set { this.aprovadoChanged = true;  this.aprovado = value; } }
        public bool IsNew { get { return this.AgendaId == 0; } }
        public Especialidade Especialidade { get; set; }
        public Medico Medico { get; set; }
        public Usuario Paciente { get; set; }
        public TimeSpan HoraInicio { get; set; }
        public TimeSpan HoraFim { get; set; }
        public bool Expirado
        {
            get { return !this.avaliado && (this.DataConsulta < DateTime.Now.Date); }
        }

        RzCorportativo.DataAccess.Agendamento model;

        public static Agenda CreateInstance(int agendaId)
        {
            Agenda e = new Agenda();
            RzCorportativo.DataAccess.RZCorporativoEntities db = new RZCorporativoEntities();
            var p = db.Agendamento.Where(w => w.AgendamentoId == agendaId).FirstOrDefault();
            if (p != null)
                e = e.CreateAgenda(p);
            return e;
        }

        public bool Salvar()
        {
            bool @result = false;
            Transaction.Begin((entity) =>
            {
                if (this.IsNew)
                    this.model = this.Insert(entity);
                else
                    this.model = this.Update(entity);
                return true;
            }).OnError((ex) =>
            {
                @result = false;
            }).OnSuccess(() =>
            {
                @result = true;
            });
            return @result;
        }

        private RzCorportativo.DataAccess.Agendamento Insert(RZCorporativoEntities entity)
        {
            var @item = this.CreateModel(entity);
            entity.AddToAgendamento(@item);
            return @item;
        }

        private RzCorportativo.DataAccess.Agendamento Update(RZCorporativoEntities entity)
        {
            var @item = this.CreateModel(entity);
            return @item;
        }

        private RzCorportativo.DataAccess.Agendamento CreateModel(RZCorporativoEntities entity)
        {
            RzCorportativo.DataAccess.Agendamento agenda = new RzCorportativo.DataAccess.Agendamento();
            if (!this.IsNew)
            {
                agenda = entity.Agendamento.Where(w => w.AgendamentoId == this.AgendaId).FirstOrDefault();
                if (agenda == null)
                    throw new Exception("Código inválido");
            }
            agenda.AgendamentoId = this.AgendaId;
            agenda.Avaliada = this.Avaliado;
            agenda.DataConsulta = this.DataConsulta;
            agenda.TipoConsultaId = this.EspecialidadeId;
            agenda.PacienteId = this.PacienteId;
            agenda.Aprovado = this.Aprovado;
            agenda.MedicoId = this.MedicoId;
            agenda.HoraFim = this.HoraFim;
            agenda.HoraInicio = this.HoraInicio;
            return agenda;
        }

        private Agenda CreateAgenda(RzCorportativo.DataAccess.Agendamento item)
        {
            Agenda agenda = new Agenda();
            agenda.AgendaId = item.AgendamentoId;
            agenda.Avaliado = item.Avaliada;
            agenda.Aprovado = item.Aprovado;
            agenda.DataConsulta = item.DataConsulta;
            agenda.EspecialidadeId = item.TipoConsultaId;
            agenda.PacienteId = item.PacienteId;
            agenda.MedicoId = item.MedicoId;
            agenda.HoraFim = item.HoraFim;
            agenda.HoraInicio = item.HoraInicio;
            if (agenda.PacienteId > 0)
                agenda.Paciente = Usuario.CreateInstace(item.PacienteId);
            else
                agenda.Paciente = new Usuario();
            if (agenda.MedicoId > 0)
                agenda.Medico = Lib.Medico.CreateInstace(agenda.MedicoId);
            else
                agenda.Medico = new Lib.Medico();
            if (agenda.EspecialidadeId > 0)
                agenda.Especialidade = Especialidade.CreateInstance(agenda.EspecialidadeId);
            else
                agenda.Especialidade = new Especialidade();
            return agenda;
        }

        public static List<Agenda> Listar(Agenda agenda, bool validaHoraInicio = false)
        {
            if (agenda == null)
                agenda = new Agenda();
            List<Agenda> lista = new List<Agenda>();
            RzCorportativo.DataAccess.RZCorporativoEntities db = new RZCorporativoEntities();

            TimeSpan horaFim = validaHoraInicio ? agenda.HoraInicio.Add(TimeSpan.Parse("01:00")) : TimeSpan.Zero;
            agenda.HoraInicio = validaHoraInicio ? agenda.HoraInicio : TimeSpan.Zero;
            lista = db.Agendamento.Where(w =>
                    ((agenda.AgendaId == 0) || (agenda.AgendaId == w.AgendamentoId)) &&
                    ((!agenda.aprovadoChanged) || (agenda.Aprovado == w.Aprovado)) &&
                    ((!agenda.avaliadoChanged) || (agenda.Avaliado == w.Avaliada)) &&
                    ((agenda.EspecialidadeId == 0) || (agenda.EspecialidadeId == w.TipoConsultaId)) &&
                    ((agenda.PacienteId == 0) || (agenda.PacienteId == w.PacienteId)) &&
                    ((agenda.MedicoId == 0) || (agenda.MedicoId == w.MedicoId)) &&
                    ((agenda.DataConsulta == DateTime.MinValue) || (w.DataConsulta == agenda.DataConsulta.Date) //(w.DataConsulta >= agenda.DataConsulta && w.DataConsulta <= agenda.DataConsulta)
                    ) &&(
                        (!validaHoraInicio) || (w.HoraInicio >= agenda.HoraInicio && w.HoraFim <= horaFim)
                    )
                    
                ).ToList().Select(s => agenda.CreateAgenda(s)).ToList();
            return lista;
        }

        public static List<Agenda> GetAgenda(Agenda agenda, bool validaHoraInicio = false)
        {
            if (agenda == null)
                agenda = new Agenda();
            List<Agenda> lista = new List<Agenda>();
            RzCorportativo.DataAccess.RZCorporativoEntities db = new RZCorporativoEntities();

            TimeSpan horaFim = validaHoraInicio ? agenda.HoraInicio.Add(TimeSpan.Parse("01:00")) : TimeSpan.Zero;
            agenda.HoraInicio = validaHoraInicio ? agenda.HoraInicio : TimeSpan.Zero;
            lista = db.Agendamento.Where(w =>
                    ((agenda.AgendaId == 0) || (agenda.AgendaId == w.AgendamentoId)) &&
                    ((!agenda.aprovadoChanged) || (agenda.Aprovado == w.Aprovado)) &&
                    ((!agenda.avaliadoChanged) || (agenda.Avaliado == w.Avaliada)) &&
                    ((agenda.EspecialidadeId == 0) || (agenda.EspecialidadeId == w.TipoConsultaId)) &&
                    ((agenda.PacienteId == 0) || (agenda.PacienteId == w.PacienteId)) &&
                    ((agenda.MedicoId == 0) || (agenda.MedicoId == w.MedicoId)) &&
                    ((agenda.DataConsulta == DateTime.MinValue) || (w.DataConsulta == agenda.DataConsulta.Date) //(w.DataConsulta >= agenda.DataConsulta && w.DataConsulta <= agenda.DataConsulta)
                    ) && (
                        (!validaHoraInicio) || (w.HoraInicio.Hours == agenda.HoraInicio.Hours)
                    )

                ).ToList().Select(s => agenda.CreateAgenda(s)).ToList();
            return lista;
        }
    }
}
